package com.gnerv.sylvanas.authentication.security.config;

import com.gnerv.sylvanas.authentication.security.service.UriAuthorityService;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.AuthorizationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.access.intercept.RequestAuthorizationContext;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.function.Supplier;

/**
 * @author Gnerv LiGen
 */
@Component
public class SylvanasAuthorizationManager implements AuthorizationManager<RequestAuthorizationContext> {

    private final UriAuthorityService uriAuthorityService;

    public SylvanasAuthorizationManager(UriAuthorityService uriAuthorityService) {
        this.uriAuthorityService = uriAuthorityService;
    }

    @Override
    public AuthorizationDecision check(Supplier<Authentication> authentication, RequestAuthorizationContext requestAuthorizationContext) {
        HttpServletRequest httpServletRequest = requestAuthorizationContext.getRequest();
        Authentication accountAuthentication = authentication.get();
        String username = accountAuthentication.getName();
        if (isSuperAdmin(username)) {
            return new AuthorizationDecision(true);
        }
        Collection<? extends GrantedAuthority> authorities = accountAuthentication.getAuthorities();
        String requestUri = httpServletRequest.getRequestURI();
        String requestMethod = httpServletRequest.getMethod();
        String authority = uriAuthorityService.selectAuthority(requestUri, requestMethod.toUpperCase());
        boolean verify = uriAuthorityService.verify(authorities, authority);
        return new AuthorizationDecision(verify);
    }

    private boolean isSuperAdmin(String username) {
        return "super".equals(username);
    }

}